using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Petra.Gis.Geometry;
using Petra.Gis.Geometry.Support;
using Petra.Gis.DataServices.WKT.Support;

namespace Petra.Gis.DataServices.WKT
{
  public partial class GeometryFactory
  {
    /***********************************************
     * 28.8.2007
     * 
     * creates Polygon
     * from wkt string
     * 
     * asida@centrum.cz, initial implementation
     *************************************************/
    private static GeometryBase ToPolygon(ref string inputStr, System.Type parentGeomType)
    {


      RegexGeometryParser rgp = new RegexGeometryParser(WKTGeometryType.Polygon);
      RegexGeometry rg = rgp.ParseGeometry(ref inputStr);

      Polygon oGeom = new Polygon();

      foreach (RegexGeometry ring in rg)
      {

        LineRing tmpGeom = ToLineRing(ring, WKTGeometryType.Polygon);
        oGeom.Add(tmpGeom);
      }

      return oGeom;

      /*
      //prepare regex expr.
      string pattern = @"(?<whitespace>\s*)" +
        @"(?<geometryname>" + getWktName[WKTGeometryType.Polygon] + ")" +
        @"(?<polygonopen>\s*\()" +
        @"((?<ringopen>\s*\()" +
        @"(?<coordinates>(\s*|\s*\,{1}\s*|\s+)\-?(\d*\.?\d+|\d+\.?\d*)([eE][+-]?\d+)?)+" +
        @"(?<ringclose>\s*\)))+" +
        @"(?<polygonclose>\s*\))"; // +
      //@"(?<invalid>[^\s]+)"; //put all regex exps here to avoid invalid chars in input string

      Match m;

      Regex r = new Regex(pattern);

      m = r.Match(inputStr);
      if (m.Length < 1)
        throw new ArgumentException("invalid input string for wkt", "inputStr");


      //validate capture ring
      if (m.Groups["ringopen"].Captures.Count != m.Groups["ringclose"].Captures.Count)
        throw new ArgumentException("invalid input string for wkt", "inputStr");

      Polygon oGeom = new Polygon();
      LineRing tmpLR;

      //foreach (Capture ring in m.Groups["ringclose"].Captures)
      for (int i = 0; i < m.Groups["ringclose"].Captures.Count;i++ )
      {
        tmpLR = ToLineRing(m.Groups["coordinates"].Captures, m.Groups["ringopen"].Captures[i], m.Groups["ringclose"].Captures[i], oGeom.GetType());
        oGeom.Add(tmpLR);
      }
      return oGeom;
       */
    }

    private static Polygon ToPolygon(RegexGeometry rg, WKTGeometryType parentGeomType)
    {
      Polygon oGeom = new Polygon();

      foreach (RegexGeometry ring in rg)
      {

        LineRing tmpGeom = ToLineRing(ring, WKTGeometryType.Polygon);
        oGeom.Add(tmpGeom);
      }

      return oGeom;
    }




    /***********************************************
     * 28.8.2007
     * 
     * creates wkt string 
     * from Polygon
     * 
     * asida@centrum.cz, initial implementation
     *************************************************/
    private static string PolygonToString(GeometryBase geometry)
    {
      string sep = "";

      //cast to Polygon first
      Polygon _polygon = (Polygon)geometry;

      System.IO.StringWriter mStrWriter = new System.IO.StringWriter();

      mStrWriter.Write(getWktName[WKTGeometryType.Polygon]);
      mStrWriter.Write("(");

      LineRing tmpLineRing;
      foreach (GeometryBase g in _polygon)
      {
        //cast GeometryBase to LineRing
        tmpLineRing = (LineRing)g;
        mStrWriter.Write(sep);
        mStrWriter.Write(LineRingToString(tmpLineRing, WKTGeometryType.Polygon));
        sep = ",";
      }

      mStrWriter.Write(")");

      return mStrWriter.ToString();
    }





    private static string PolygonToString(Polygon geometry, WKTGeometryType parentGeometryType)
    {

      string sep = "";

      //cast to Polygon first
      Polygon _polygon = (Polygon)geometry;

      System.IO.StringWriter mStrWriter = new System.IO.StringWriter();

      if (!(parentGeometryType == WKTGeometryType.MultiPolygon || parentGeometryType == WKTGeometryType.GeometryCollection))
        mStrWriter.Write(getWktName[WKTGeometryType.Polygon]);

      mStrWriter.Write("(");

      LineRing tmpLineRing;
      foreach (GeometryBase g in _polygon)
      {
        //cast GeometryBase to LineRing
        tmpLineRing = (LineRing)g;
        mStrWriter.Write(sep);
        mStrWriter.Write(LineRingToString(tmpLineRing, WKTGeometryType.Polygon));
        sep = ",";
      }

      mStrWriter.Write(")");

      return mStrWriter.ToString();
    }
  }
}
